//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================


/*
 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Thomas Roell not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Thomas Roell makes no representations
 * about the suitability of this software for any purpose.  It is provided
 * "as is" without express or implied warranty.
 *
 * THOMAS ROELL, KEVIN E. MARTIN, RICKARD E. FAITH, SCOTT LAIRD,
 * AND TIAGO GONS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
 * SHALL THOMAS ROELL, KEVIN E. MARTIN, RICKARD E. FAITH, SCOTT LAIRD, OR
 * TIAGO GONS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 * Author:  Thomas Roell, roell@informatik.tu-muenchen.de
 *
 * Rewritten for the 8514/A by Kevin E. Martin (martin@cs.unc.edu)
 * Modified for the Mach-8 by Rickard E. Faith (faith@cs.unc.edu)
 * Further modifications by Scott Laird (lair@kimbark.uchicago.edu)
 * and Tiago Gons (tiago@comosjn.hobby.nl)
 *
 */

#include <ddk.h>
#include <osenv.h>
#include "X.h"
#include "scrnintstr.h"
#include "compiler.h"
#include "xf86.h"
#include "xf86Priv.h"
#include "xf86_OSlib.h"
#include "xf86_HWlib.h"

/*
 * xf86GetClocks -- generalized version of (old) vgaGetClocks
 *      get the dot-clocks via a BIG BAD hack ...
 */
void
xf86GetClocks(int num,
        Boolean (*ClockFunc)(int),
        void (*ProtectRegs)(Boolean),
        SaveScreenProcPtr SaveScreen(ScreenPtr pScreen, Boolean on),
        int vertsyncreg,
        int maskval,
        int knownclkindex,
        int knownclkvalue,
        ScrnInfoRec *InfoRec)
{
#if 0
    register int status = vertsyncreg;
    unsigned long cnt, rcnt, sync;
    int i;

    /* First save registers that get written on */
    (*ClockFunc)(CLK_REG_SAVE);


    for (i = 0; i < num; i++) {
        (*ProtectRegs)(TRUE);
        if (!(*ClockFunc)(i)) {
            InfoRec->clock[i] = -1;
            continue;
        }
        (*ProtectRegs)(FALSE);
        (*SaveScreen)(NULL, FALSE);

        //_CThread_Sleep(50000);     /* let VCO stabilise */

        cnt  = 0;
        sync = 200000;

        if (!xf86DisableInterrupts()) {
            (*ClockFunc)(CLK_REG_RESTORE);
            kprintf("Failed to disable interrupts during clock probe.  If\n");
            kprintf("your OS does not support disabling interrupts, then you\n");
            kprintf("must specify a Clocks line in the XF86Config file.\n");
        }
        while ((Inb(status) & maskval) == 0x00) {
            if (sync-- == 0)
                goto finish;
        }
        /* Something appears to be happening, so reset sync count */
        sync = 200000;
        while ((Inb(status) & maskval) == maskval) {
            if (sync-- == 0)
                goto finish;
        }
        /* Something appears to be happening, so reset sync count */
        sync = 200000;
        while ((Inb(status) & maskval) == 0x00) {
            if (sync-- == 0)
                goto finish;
        }

        for (rcnt = 0; rcnt < 5; rcnt++)  {
            while (!(Inb(status) & maskval))
                cnt++;
            while ((Inb(status) & maskval))
                cnt++;
        }

finish:
        xf86EnableInterrupts();

        InfoRec->clock[i] = cnt ? cnt : (long unsigned int)-1;
        (*SaveScreen)(NULL, TRUE);
    }


    for (i = 0; i < num; i++) {
        if (i != knownclkindex) {
            if (InfoRec->clock[i] == -1) {
                InfoRec->clock[i] = 0;
            }
            else {
                InfoRec->clock[i] = (int)(0.5 +
                    (((float)knownclkvalue) * InfoRec->clock[knownclkindex]) /
                    (InfoRec->clock[i]));
                /* Round to nearest 10KHz */
                InfoRec->clock[i] += 5;
                InfoRec->clock[i] /= 10;
                InfoRec->clock[i] *= 10;
            }
        }
    }

    InfoRec->clock[knownclkindex] = knownclkvalue;
    InfoRec->clocks = num;

    /* Restore registers that were written on */
    (*ClockFunc)(CLK_REG_RESTORE);
#endif
}
